home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 February: Tool Chest / Dev.CD Feb 99 TC.toast / What's New? / Development Kits / Mac OS USB v1.1f3 DDK / Examples / KeyboardModule / KeyIn.c < prev   
Encoding:
C/C++ Source or Header  |  1999-01-07  |  11.3 KB  |  491 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        KeyIn.c
  3.  
  4.     Contains:    ADB keyboard simulation (non-shim based).
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1998 by Apple Computer, Inc., all rights reserved.
  9. */
  10.  
  11. /*
  12.  USB Keyboard Translation to Macintosh 
  13.  */
  14.  
  15. #include <Types.h>
  16. #include <Events.h>
  17. #include <Resources.h>
  18. #include <LowMem.h>
  19. #include <USB.h>
  20. #include "KeyboardModule.h"
  21.  
  22.  
  23. #define DOWN        0
  24. #define UP            1
  25.  
  26. #define TRUE        1
  27. #define FALSE        0
  28.  
  29. #define FakeADBAddr        16
  30. #define FakeKBDType        2        // this should be the same as the Apple extended keyboard for now
  31.  
  32. static UInt32    myKeyMAP[4];
  33. static UInt32    keyTransState;
  34. static Handle    handleKCHR;
  35. static UInt8*    KCHRptr;
  36.  
  37. typedef KeyMap * KeyMapPtr;
  38.  
  39. /* prototypes */
  40. Boolean KeyInArray(UInt8 key, UInt8 *array, UInt16 len);
  41. Boolean SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value); 
  42. void  PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state);
  43.  
  44. /* when we move to master interfaces we can get this stuff from LowMemPriv.h */
  45. /* be sure to turn on DIRECT_LOWMEM_ACCESSORS */
  46. #define LMSetKbdVars(value) ((*(short *)0x0216) = (value))
  47. #define LMSetKeyLast(value) ((*(short *)0x0184) = (value))
  48. #define LMSetKeyTime(value) ((*(long *)0x0186) = (value))
  49. #define LMSetKeyRepTime(value) ((*(long *)0x018A) = (value))
  50. #define LMSetKeyMap(KeyMapValue)    BlockMove((Ptr)(KeyMapValue), (Ptr)0x0174, sizeof(KeyMap))
  51.  
  52.  
  53. // index represents USB keyboard usage value, content is Mac virtual keycode
  54. static UInt8    USBKMAP[256] = {  
  55.     0xFF,     /* 00 no event */        
  56.     0xFF,    /* 01 ErrorRollOver */    
  57.     0xFF,    /* 02 POSTFail */    
  58.     0xFF,    /* 03 ErrorUndefined */    
  59.     0x00,    /* 04 A */
  60.     0x0B,    /* 05 B */
  61.     0x08,    /* 06 C */
  62.     0x02,    /* 07 D */
  63.     0x0E,    /* 08 E */
  64.     0x03,    /* 09 F */
  65.     0x05,    /* 0A G */
  66.     0x04,    /* 0B H */
  67.     0x22,    /* 0C I */
  68.     0x26,    /* 0D J */
  69.     0x28,    /* 0E K */
  70.     0x25,    /* 0F L */
  71.  
  72.     0x2E,     /* 10 M */        
  73.     0x2D,    /* 11 N */    
  74.     0x1F,    /* 12 O */    
  75.     0x23,    /* 13 P */    
  76.     0x0C,    /* 14 Q */
  77.     0x0F,    /* 15 R */
  78.     0x01,    /* 16 S */
  79.     0x11,    /* 17 T */
  80.     0x20,    /* 18 U */
  81.     0x09,    /* 19 V */
  82.     0x0D,    /* 1A W */
  83.     0x07,    /* 1B X */
  84.     0x10,    /* 1C Y */
  85.     0x06,    /* 1D Z */
  86.     0x12,    /* 1E 1/! */
  87.     0x13,    /* 1F 2/@ */
  88.  
  89.     0x14,     /* 20 3 # */        
  90.     0x15,    /* 21 4 $ */    
  91.     0x17,    /* 22 5 % */    
  92.     0x16,    /* 23 6 ^ */    
  93.     0x1A,    /* 24 7 & */
  94.     0x1C,    /* 25 8 * */
  95.     0x19,    /* 26 9 ( */
  96.     0x1D,    /* 27 0 ) */
  97.     0x24,    /* 28 Return (Enter) */
  98.     0x35,    /* 29 ESC */
  99.     0x33,    /* 2A Delete (Backspace) */
  100.     0x30,    /* 2B Tab */
  101.     0x31,    /* 2C Spacebar */
  102.     0x1B,    /* 2D - _ */
  103.     0x18,    /* 2E = + */
  104.     0x21,    /* 2F [ { */
  105.  
  106.     0x1E,     /* 30 ] } */        
  107.     0x2A,    /* 31 \ | */    
  108.     0xFF,    /* 32 Non-US # and ~ (what?!!!) */    
  109.     0x29,    /* 33 ; : */    
  110.     0x27,    /* 34 ' " */
  111.     0x32,    /* 35 ` ~ */
  112.     0x2B,    /* 36 , < */
  113.     0x2F,    /* 37 . > */
  114.     0x2C,    /* 38 / ? */
  115.     0x39,    /* 39 Caps Lock */
  116.     0x7A,    /* 3A F1 */
  117.     0x78,    /* 3B F2 */
  118.     0x63,    /* 3C F3 */
  119.     0x76,    /* 3D F4 */
  120.     0x60,    /* 3E F5 */
  121.     0x61,    /* 3F F6 */
  122.  
  123.     0x62,     /* 40 F7 */        
  124.     0x64,    /* 41 F8 */    
  125.     0x65,    /* 42 F9 */    
  126.     0x6D,    /* 43 F10 */    
  127.     0x67,    /* 44 F11 */
  128.     0x6F,    /* 45 F12 */
  129.     0x69,    /* 46 F13/PrintScreen */
  130.     0x6B,    /* 47 F14/ScrollLock */
  131.     0x71,    /* 48 F15/Pause */                
  132.     0x72,    /* 49 Insert */
  133.     0x73,    /* 4A Home */
  134.     0x74,    /* 4B PageUp */
  135.     0x75,    /* 4C Delete Forward */
  136.     0x77,    /* 4D End */
  137.     0x79,    /* 4E PageDown */
  138.     0x7C,    /* 4F RightArrow */
  139.  
  140.     0x7B,     /* 50 LeftArrow */        
  141.     0x7D,    /* 51 DownArrow */    
  142.     0x7E,    /* 52 UpArrow */    
  143.     0x47,    /* 53 NumLock/Clear */    
  144.     0x4B,    /* 54 Keypad / */
  145.     0x43,    /* 55 Keypad * */
  146.     0x4E,    /* 56 Keypad - */
  147.     0x45,    /* 57 Keypad + */
  148.     0x4C,    /* 58 Keypad Enter */
  149.     0x53,    /* 59 Keypad 1 */
  150.     0x54,    /* 5A Keypad 2 */
  151.     0x55,    /* 5B Keypad 3 */
  152.     0x56,    /* 5C Keypad 4 */
  153.     0x57,    /* 5D Keypad 5 */
  154.     0x58,    /* 5E Keypad 6 */
  155.     0x59,    /* 5F Keypad 7 */
  156.  
  157.     0x5B,     /* 60 Keypad 8 */        
  158.     0x5C,    /* 61 Keypad 9 */    
  159.     0x52,    /* 62 Keypad 0 */    
  160.     0x41,    /* 63 Keypad . */    
  161.     0xFF,    /* 64 Non-US \ and  | (what ??!!) */
  162.     0x6E,    /* 65 ApplicationKey (not on a mac!)*/
  163.     0x7F,    /* 66 PowerKey  */
  164.     0x51,    /* 67 Keypad = */
  165.     0x69,    /* 68 F13 */
  166.     0x6B,    /* 69 F14 */
  167.     0x71,    /* 6A F15 */
  168.     0xFF,    /* 6B F16 */
  169.     0xFF,    /* 6C F17 */
  170.     0xFF,    /* 6D F18 */
  171.     0xFF,    /* 6E F19 */
  172.     0xFF,    /* 6F F20 */
  173.  
  174.     0x5B,     /* 70 F21 */        
  175.     0x5C,    /* 71 F22 */    
  176.     0x52,    /* 72 F23 */    
  177.     0x41,    /* 73 F24 */    
  178.     0xFF,    /* 74 Execute */
  179.     0xFF,    /* 75 Help */
  180.     0x7F,    /* 76 Menu */
  181.     0x4C,    /* 77 Select */
  182.     0x69,    /* 78 Stop */
  183.     0x6B,    /* 79 Again */
  184.     0x71,    /* 7A Undo */
  185.     0xFF,    /* 7B Cut */
  186.     0xFF,    /* 7C Copy */
  187.     0xFF,    /* 7D Paste */
  188.     0xFF,    /* 7E Find */
  189.     0xFF,    /* 7F Mute */
  190.     
  191.     0xFF,     /* 80 no event */        
  192.     0xFF,    /* 81 no event */    
  193.     0xFF,    /* 82 no event */    
  194.     0xFF,    /* 83 no event */    
  195.     0xFF,    /* 84 no event */
  196.     0xFF,    /* 85 no event */
  197.     0xFF,    /* 86 no event */
  198.     0xFF,    /* 87 no event */
  199.     0xFF,    /* 88 no event */
  200.     0xFF,    /* 89 no event */
  201.     0xFF,    /* 8A no event */
  202.     0xFF,    /* 8B no event */
  203.     0xFF,    /* 8C no event */
  204.     0xFF,    /* 8D no event */
  205.     0xFF,    /* 8E no event */
  206.     0xFF,    /* 8F no event */
  207.  
  208.     0xFF,     /* 90 no event */        
  209.     0xFF,    /* 91 no event */    
  210.     0xFF,    /* 92 no event */    
  211.     0xFF,    /* 93 no event */    
  212.     0xFF,    /* 94 no event */
  213.     0xFF,    /* 95 no event */
  214.     0xFF,    /* 96 no event */
  215.     0xFF,    /* 97 no event */
  216.     0xFF,    /* 98 no event */
  217.     0xFF,    /* 99 no event */
  218.     0xFF,    /* 9A no event */
  219.     0xFF,    /* 9B no event */
  220.     0xFF,    /* 9C no event */
  221.     0xFF,    /* 9D no event */
  222.     0xFF,    /* 9E no event */
  223.     0xFF,    /* 9F no event */
  224.  
  225.     0xFF,     /* A0 no event */        
  226.     0xFF,    /* A1 no event */    
  227.     0xFF,    /* A2 no event */    
  228.     0xFF,    /* A3 no event */    
  229.     0xFF,    /* A4 no event */
  230.     0xFF,    /* A5 no event */
  231.     0xFF,    /* A6 no event */
  232.     0xFF,    /* A7 no event */
  233.     0xFF,    /* A8 no event */
  234.     0xFF,    /* A9 no event */
  235.     0xFF,    /* AA no event */
  236.     0xFF,    /* AB no event */
  237.     0xFF,    /* AC no event */
  238.     0xFF,    /* AD no event */
  239.     0xFF,    /* AE no event */
  240.     0xFF,    /* AF no event */
  241.  
  242.     0xFF,     /* B0 no event */        
  243.     0xFF,    /* B1 no event */    
  244.     0xFF,    /* B2 no event */    
  245.     0xFF,    /* B3 no event */    
  246.     0xFF,    /* B4 no event */
  247.     0xFF,    /* B5 no event */
  248.     0xFF,    /* B6 no event */
  249.     0xFF,    /* B7 no event */
  250.     0xFF,    /* B8 no event */
  251.     0xFF,    /* B9 no event */
  252.     0xFF,    /* BA no event */
  253.     0xFF,    /* BB no event */
  254.     0xFF,    /* BC no event */
  255.     0xFF,    /* BD no event */
  256.     0xFF,    /* BE no event */
  257.     0xFF,    /* BF no event */
  258.  
  259.     0xFF,     /* C0 no event */        
  260.     0xFF,    /* C1 no event */    
  261.     0xFF,    /* C2 no event */    
  262.     0xFF,    /* C3 no event */    
  263.     0xFF,    /* C4 no event */
  264.     0xFF,    /* C5 no event */
  265.     0xFF,    /* C6 no event */
  266.     0xFF,    /* C7 no event */
  267.     0xFF,    /* C8 no event */
  268.     0xFF,    /* C9 no event */
  269.     0xFF,    /* CA no event */
  270.     0xFF,    /* CB no event */
  271.     0xFF,    /* CC no event */
  272.     0xFF,    /* CD no event */
  273.     0xFF,    /* CE no event */
  274.     0xFF,    /* CF no event */
  275.  
  276.     0xFF,     /* D0 no event */        
  277.     0xFF,    /* D1 no event */    
  278.     0xFF,    /* D2 no event */    
  279.     0xFF,    /* D3 no event */    
  280.     0xFF,    /* D4 no event */
  281.     0xFF,    /* D5 no event */
  282.     0xFF,    /* D6 no event */
  283.     0xFF,    /* D7 no event */
  284.     0xFF,    /* D8 no event */
  285.     0xFF,    /* D9 no event */
  286.     0xFF,    /* DA no event */
  287.     0xFF,    /* DB no event */
  288.     0xFF,    /* DC no event */
  289.     0xFF,    /* DD no event */
  290.     0xFF,    /* DE no event */
  291.     0xFF,    /* DF no event */
  292.  
  293.     0x3B,     /* E0 left control key */        
  294.     0x38,    /* E1 left shift key key */    
  295.     0x3A,    /* E2 left alt/option key */    
  296.     0x37,    /* E3 left GUI (windows/cmd) key */    
  297.     
  298.     0x3B,    /* E4 right control key */ 
  299.     0x38,    /* E5 right shift key key */ 
  300.     0x3A,    /* E6 right alt/option key */ 
  301.     0x37,    /* E7 right GUI (windows/cmd) key */
  302.     0xFF,    /* E8 no event */
  303.     0xFF,    /* E9 no event */
  304.     0xFF,    /* EA no event */
  305.     0xFF,    /* EB no event */
  306.     0xFF,    /* EC no event */
  307.     0xFF,    /* ED no event */
  308.     0xFF,    /* EE no event */
  309.     0xFF,    /* EF no event */
  310.     
  311.     0xFF,     /* F0 no event */        
  312.     0xFF,    /* F1 no event */    
  313.     0xFF,    /* F2 no event */    
  314.     0xFF,    /* F3 no event */    
  315.     0xFF,    /* F4 no event */
  316.     0xFF,    /* F5 no event */
  317.     0xFF,    /* F6 no event */
  318.     0xFF,    /* F7 no event */
  319.     0xFF,    /* F8 no event */
  320.     0xFF,    /* F9 no event */
  321.     0xFF,    /* FA no event */
  322.     0xFF,    /* FB no event */
  323.     0xFF,    /* FC no event */
  324.     0xFF,    /* FD no event */
  325.     0xFF,    /* FE no event */
  326.     0xFF,    /* FF no event */
  327. };
  328.         
  329. void
  330. InitUSBKeyboard()
  331. {
  332.     handleKCHR = GetResource('KCHR',0);    // US keyboard mapping (handled differently by ADB Mgr)
  333.     HLock(handleKCHR);
  334.     KCHRptr = (UInt8 *)*handleKCHR;
  335. }
  336.  
  337.  
  338.  
  339. void PostUSBKeyToMac(UInt16 rawUSBkey)
  340. {
  341. static    UInt8    oldLEDState = 0x00;
  342. static    UInt8    newLEDState = 0x00;
  343.  
  344. static    UInt8    capsLockState = 0x00;
  345. static    UInt8    numLockState = 0x00;
  346. static    UInt8    scrollLockState = 0x00;
  347.  
  348. register UInt8    virtualKeycode, keystate;
  349.  
  350.     
  351.     if (KCHRptr == 0)
  352.     {
  353.         InitUSBKeyboard();
  354.     }
  355.     
  356.     keystate = (rawUSBkey & 0x8000) ? UP : DOWN;
  357.     rawUSBkey &= 0x0FF;
  358.     
  359.     if (keystate == DOWN)
  360.     {
  361.         newLEDState = oldLEDState;
  362.         
  363.         switch (rawUSBkey)
  364.         {
  365. // Note:  This switch statement is being left it to make it easy to add "toggling" keys in the future.
  366. //        it used to support toggled numlock & scroll lock...  It doesn't anymore.
  367.             case kUSBCapsLockKey:
  368.                 newLEDState ^= (1 << kCapsLockLED);
  369.                 keystate = (newLEDState & (1 << kCapsLockLED)) ? DOWN : UP;
  370.                 break;
  371.         }
  372.         
  373.         if (newLEDState != oldLEDState)
  374.         {
  375.             oldLEDState = newLEDState;
  376.             USBHIDControlDevice(kHIDSetLEDStateByBits, &newLEDState);
  377.         }
  378.     }
  379.     else
  380.     {
  381.         switch (rawUSBkey)
  382.         {
  383. // Note:  This switch statement is being left it to make it easy to add "toggling" keys in the future.
  384.             case kUSBCapsLockKey:
  385.                 return;
  386.                 break;
  387.         }
  388.     }
  389.     
  390.     // look up rawUSBkey in KMAP resource to get virtual keycode
  391.     if (rawUSBkey < sizeof(USBKMAP))
  392.     {
  393.         virtualKeycode = USBKMAP[rawUSBkey];
  394.     } 
  395.     else 
  396.     {
  397. //        DebugStr("\pPostUSBKeyToMac: Need bigger KMAP table");
  398.         virtualKeycode = 0xFF;
  399.     }
  400.  
  401.     PostADBKeyToMac(virtualKeycode, keystate);
  402.     if (virtualKeycode == 0x7F)
  403.         PostADBKeyToMac(virtualKeycode, keystate);
  404. }
  405.  
  406. void 
  407. PostADBKeyToMac(UInt16 virtualKeycode, UInt8 state)
  408. {
  409.     UInt32    keyEventMsg;
  410.     
  411.     if (virtualKeycode > 127) return;  // not handled by MacOS!
  412.     
  413.     // stop repeating
  414.     LMSetKeyLast(0);
  415.     LMSetKbdVars(0);
  416.     
  417.     // update our keymap
  418.     SetBit((UInt8 *)myKeyMAP, virtualKeycode, state == DOWN ? 1 : 0);
  419.     LMSetKeyMap(&myKeyMAP);
  420.  
  421.     // set this keyboard as the last keyboard
  422.     LMSetKbdLast(FakeADBAddr);
  423.     LMSetKbdType(FakeKBDType);
  424.     
  425.     // call KeyTrans to get character code
  426.     virtualKeycode |= ((myKeyMAP[1]<<9) & 0x00FE00) | ((myKeyMAP[1]>>7) & 0x0100) | ((state==UP) ? 0x080 : 0);
  427.     keyEventMsg = KeyTranslate(KCHRptr, virtualKeycode , &keyTransState);
  428.     virtualKeycode &= 0x7F;
  429.     
  430.     if (keyEventMsg & 0xFFFF0000) {
  431.         // post event
  432.         UInt32 event =(keyEventMsg & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00)  | ((keyEventMsg>>16) & 0x0FF);
  433.         if (state == DOWN){
  434.             UInt32 ticks = TickCount();
  435.             LMSetKeyTime(ticks);
  436.             LMSetKeyRepTime(ticks);
  437.             LMSetKeyLast(event & 0x0FFFF);
  438.             LMSetKbdVars((event>>16) & 0x0FFFF);
  439.         }        
  440.         PostEvent((state == DOWN ? keyDown : keyUp), event);
  441.     }
  442.     if (keyEventMsg & 0x0000FFFF) {
  443.         // post event
  444.         UInt32 event =((keyEventMsg<<16) & 0xFF000000) | ((FakeADBAddr << 16) & 0x0FF0000) | ((virtualKeycode << 8) & 0x0FF00)  | (keyEventMsg & 0x0FF);
  445.         if (state == DOWN){
  446.             UInt32 ticks = TickCount();
  447.             LMSetKeyTime(ticks);
  448.             LMSetKeyRepTime(ticks);
  449.             LMSetKeyLast(event & 0x0FFFF);
  450.             LMSetKbdVars((event>>16) & 0x0FFFF);
  451.         }        
  452.         PostEvent((state == DOWN ? keyDown : keyUp), event);
  453.     }
  454. }
  455.  
  456. // Sets the bitmapArray[index] to value
  457. // returns old value;
  458. Boolean
  459. SetBit(UInt8 *bitmapArray, UInt16 index, Boolean value)
  460. {    
  461.     UInt32    mask = 0x1 << (index % 8 );
  462.     Boolean    oldVal;
  463.     
  464.     oldVal = (bitmapArray[index/8] & mask) ? TRUE : FALSE;
  465.     
  466.     if (value){
  467.         bitmapArray[index/8] |= mask;
  468.     }else{
  469.         bitmapArray[index/8] &= ~mask;
  470.     }
  471.     
  472.     return (oldVal);
  473. }
  474.  
  475. void USBDemoKeyIn(UInt32 refcon, void * theData)
  476. {
  477. #pragma unused (refcon)
  478.  
  479. USBHIDDataPtr    pTheKeyboardData;
  480. register        UInt8    i;
  481.  
  482.     pTheKeyboardData = (USBHIDDataPtr)theData;
  483.     for (i=0; i<pTheKeyboardData->kbd.keycount; i++)
  484.     {
  485.         // no shim installed, let's just post some Macintosh keyevents
  486.         PostUSBKeyToMac(pTheKeyboardData->kbd.usbkeycode[i]);
  487.     }
  488.  
  489. }
  490.  
  491.